//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS__SCHEDULE_H__
#define __ELASTOS__SCHEDULE_H__

//
// ScheduleClass
//
enum ScheduleClassType
{
    ScheduleClassType_Idle          = 1,
    ScheduleClassType_TimeSharing   = 2,
    ScheduleClassType_SoftRealTime  = 3,
    ScheduleClassType_HardRealTime  = 4,
};

#define NUMBEROF_THREAD_PRIORITIES \
        (ThreadPriority_Highest - ThreadPriority_Lowest + 1)

enum RunningReason
{
    RunningReason_Initialize,
    RunningReason_WakeUp,
    RunningReason_Resume,
    RunningReason_Other,
};

class ScheduleClass
{
friend INLINE bool_t PriorityGreaterThan(
        const ScheduleClass *pScheduleClass1, uint_t uPriority1,
        const ScheduleClass *pScheduleClass2, uint_t uPriority2);

public:
    virtual void Initialize() = 0;

    virtual void InitializeThread(Thread *pThread) = 0;

    virtual void SetThreadPriority(
        Thread *pThread, ThreadPriority priority, bool_t bRunning) = 0;
    virtual ThreadPriority GetThreadPriority(Thread *pThread) = 0;

    virtual void OnThreadSleep(Thread *pThread) = 0;
    virtual void OnThreadWakeUp(Thread *pThread) = 0;

    virtual void OnThreadYield(Thread *pThread) = 0;

    virtual void OnThreadSwitchOut(Thread *pThread) = 0;

    virtual void EnterRunningList(
        Thread *pThread, RunningReason reason) = 0;
    virtual void LeaveRunningList(Thread *pThread) = 0;

    virtual void UpdateTime(uint_t uTicks) = 0;
    virtual bool_t UpdateThreadTime(Thread *pThread, uint_t uTicks) = 0;

    virtual Thread *SelectNextThread() = 0;

protected:
    ScheduleClassType   m_type;
};

#define PRIORITY_SIGNIFICANT_BITS   24

INLINE bool_t PriorityGreaterThan(
    const ScheduleClass *pScheduleClass1, uint_t uPriority1,
    const ScheduleClass *pScheduleClass2, uint_t uPriority2)
{
    assert(pScheduleClass1);
    assert(pScheduleClass2);

    return ((pScheduleClass1->m_type << PRIORITY_SIGNIFICANT_BITS) + uPriority1)
        > ((pScheduleClass2->m_type << PRIORITY_SIGNIFICANT_BITS) + uPriority2);
}

INLINE bool_t PriorityGreaterThan(
    const Thread *pThread1, const Thread *pThread2)
{
    assert(pThread1);
    assert(pThread2);

    return PriorityGreaterThan(
        pThread1->m_pEffectiveScheduleClass,
        pThread1->m_uEffectiveDynamicPriority,
        pThread2->m_pEffectiveScheduleClass,
        pThread2->m_uEffectiveDynamicPriority);
}

#include <_schedule/idle.h>
#include <_schedule/tsharing.h>
#include <_schedule/srealtime.h>

#endif // __ELASTOS__SCHEDULE_H__
